/*
 * JGO2RDF creates a RDF representation of GAF2 files, which are automatically sourced from GO ftp site.
 * Copyright (C) 2012 Matthew M. Hindle & Artem Lysenko
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package uk.co.jgo2rdf.goa.model;

import uk.co.jgo2rdf.exception.ValueNotSetException;

import java.util.Arrays;

/**
 * Establishes duplicate entries based on GOID, GeneID, Evidence, Assignee, Qualifier, and taxons
 * <p/>
 * Created by IntelliJ IDEA.
 * User: UNBSJ
 * Date: 4/11/11
 * Time: 10:54 AM
 * TODO exception handling makes this class really ugly fix
 * To change this template use File | Settings | File Templates.
 */
public abstract class GOAUniqueMutableEntry implements MutableGOAEntry {

    public boolean equals(Object obj) {
        if (super.equals(obj)) return true;

        if (obj instanceof GOAEntry) {
            GOAEntry compEnt = (GOAEntry) obj;

            if (compEnt.getGO_ID() != this.getGO_ID()) return false;   //go term not same
            if (!compEnt.getEvidenceCode().equals(this.getEvidenceCode())) return false; //evidence not same
            if (!compEnt.getDBObject_ID().equals(this.getDBObject_ID())) return false;  //gene not same
            if (!compEnt.getAssignedBy().equals(this.getAssignedBy())) return false; //asignee not same

            if (compEnt.hasQualifier() != this.hasQualifier()) return false;
            else if (compEnt.hasQualifier() && !compEnt.getQualifier().equals(this.getQualifier())) return false;

            if (compEnt.hasWithFrom() != this.hasWithFrom()) return false;
            else if (compEnt.hasWithFrom() && !compEnt.getWithFrom().equals(this.getWithFrom())) return false;

            return Arrays.equals(compEnt.getTaxons(), this.getTaxons());

        }
        return false;
    }

    /**
     * A very inefficant toString method [NOT for computation or comparison!]
     *
     * @return a human readable version of this entry
     */
    public String toString() {
        StringBuilder sb = new StringBuilder("[");
        try {
            sb.append(this.getDB());
        } catch (ValueNotSetException e) {//do nothing
        }
        sb.append(',');
        try {
            sb.append(this.getDBObject_ID());
        } catch (ValueNotSetException e) {//do nothing
        }
        sb.append(',');
        sb.append(this.getDBObjectSymbol());
        if (this.hasQualifier())
            try {
                sb.append(',').append(this.getQualifier());
            } catch (ValueNotSetException e) { //do nothing
            }
        sb.append(',');
        try {
            sb.append(this.getGO_ID());
        } catch (ValueNotSetException e) {//do nothing
        }
        sb.append(',');
        try {
            sb.append(this.getEvidenceCode());
        } catch (ValueNotSetException e) { //do nothing
        }
        sb.append(',');
        try {
            sb.append(this.getWithFrom());
        } catch (ValueNotSetException e) { //do nothing
        }
        sb.append(',');
        try {
            sb.append(this.getAspect());
        } catch (ValueNotSetException e) {//do nothing
        }
        sb.append(',');
        try {
            sb.append(this.getDBObjectName());
        } catch (ValueNotSetException e) {//do nothing
        }
        sb.append(',');
        if (this.hasDBObjectSynonym())
            try {
                sb.append(this.getDBObjectSynonym());
            } catch (ValueNotSetException e) {//do nothing
            }
        sb.append(',');
        try {
            sb.append(this.getDBObjectType());
        } catch (ValueNotSetException e) {//do nothing
        }
        try {
            sb.append(Arrays.toString(this.getTaxons()));
        } catch (ValueNotSetException e) {//do nothing
        }
        sb.append(',');
        try {
            sb.append(this.getDate());
        } catch (ValueNotSetException e) { //do nothing
        }
        sb.append(',');
        try {
            sb.append(this.getAssignedBy());
        } catch (ValueNotSetException e) {//do nothing
        }
        if (this.hasAnnotation_Extension())
            try {
                sb.append(',').append(this.getAnnotation_Extension());
            } catch (ValueNotSetException e) { //do nothing
            }
        if (this.hasGeneProductFormID())
            try {
                sb.append(',').append(this.getGeneProductFormID());
            } catch (ValueNotSetException e) { //do nothing
            }
        sb.append(']');
        return sb.toString();
    }

    private final static int prime = 31;

    public int hashCode() {
        int result = getGO_ID();
        result = result * prime + getEvidenceCode().hashCode();
        if (this.hasWithFrom()) result = result * prime + this.getWithFrom().hashCode();
        if (this.hasQualifier()) result = result * prime + this.getQualifier().hashCode();
        return result;
    }

}
